package com.endlessblue.visa.vo;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

import com.endlessblue.visa.util.JsonUtil;
import com.endlessblue.visa.util.PropertyUtil;


/**
 * 请求参数校验
 * @author sonta
 */
@Component
public class ReqParamCheck {
    
	
	public static enum InterfaceType{
		
		// 登录
		LOGIN (
				"LOGIN", "登录",
				"["
				+ "{\"enName\":\"userAccount\",\"cnName\":\"用户名\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^([1][0-9]{10})|(([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,})$\",\"errorTip\":\"格式非法(只能为邮箱或手机号)\"}"
				+ ",{\"enName\":\"userPwd\",\"cnName\":\"密码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
				+ "]"
		),
		// 登出
		LOGOUT (
				"LOGOUT", "登出",
				"["
						+ "{\"enName\":\"userId\",\"cnName\":\"用户ID\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ "]"
				),
		// 注册
		REGISTER (
				"REGISTER", "注册",
				"["
				+ "{\"enName\":\"userAccount\",\"cnName\":\"用户名\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^([1][0-9]{10})|(([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,})$\",\"errorTip\":\"格式非法(只能为邮箱或手机号)\"}"
				+ ",{\"enName\":\"userPwd\",\"cnName\":\"密码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
				+ ",{\"enName\":\"authCode\",\"cnName\":\"验证码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^[0-9]{4,}$\",\"errorTip\":\"验证码为4位以上的纯数字组合\"}"
				+ ",{\"enName\":\"nickName\",\"cnName\":\"昵称\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\",\"errorTip\":\"\"}"
				+ ",{\"enName\":\"headPhoto\",\"cnName\":\"头像\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\",\"errorTip\":\"\"}"
				+ "]"
				),
		// 找回密码
		FINDPWD (
				"FINDPWD", "找回密码",
				"["
				+ "{\"enName\":\"userAccount\",\"cnName\":\"用户名\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^([1][0-9]{10})|(([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,})$\",\"errorTip\":\"格式非法(只能为邮箱或手机号)\"}"
				+ ",{\"enName\":\"authCode\",\"cnName\":\"验证码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^[0-9]{4,}$\",\"errorTip\":\"验证码为4位以上的纯数字组合\"}"
				+ ",{\"enName\":\"newPwd\",\"cnName\":\"新密码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
				+ "]"
		),
		// 找回密码
		CHANGEPWD (
				"CHANGEPWD", "修改密码",
				"["
						+ "{\"enName\":\"userAccount\",\"cnName\":\"用户名\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^([1][0-9]{10})|(([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,})$\",\"errorTip\":\"格式非法(只能为邮箱或手机号)\"}"
						+ ",{\"enName\":\"oldPwd\",\"cnName\":\"旧密码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ ",{\"enName\":\"newPwd\",\"cnName\":\"新密码\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ "]"
				),
		// 同步客户端签证记录至服务端
		SYNCVH2SERVER (
				"SYNCVH2SERVER", "同步客户端签证记录至服务端",
				"["
				+ "{\"enName\":\"vid\",\"cnName\":\"签证ID\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\":\"\"}"
				+ ",{\"enName\":\"records\",\"cnName\":\"签证记录\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
				+ "]"
				),
		// 同步客户端签证记录至客户端
		SYNCVH2CLIENT (
				"SYNCVH2CLIENT", "同步客户端签证记录至客户端",
				"["
				+ "{\"enName\":\"visaId\",\"cnName\":\"签证ID\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\":\"\"}"
				+ ",{\"enName\":\"lastGTime\",\"cnName\":\"最后一次签证记录时间\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
				+ "]"
				),
		// 同步客户端签证记录至客户端
		ADDVISA (
				"ADDVISA", "添加新的签证",
				"["
						+ "{\"enName\":\"validity\",\"cnName\":\"有效期\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^[1-9][0-9]*$\",\"errorTip\":\"必须为大于0的整数\"}"
						+ ",{\"enName\":\"beginTime\",\"cnName\":\"开始日期\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ ",{\"enName\":\"totalInTime\",\"cnName\":\"入境有效期\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ ",{\"enName\":\"visaName\",\"cnName\":\"名称\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"notEmpty\",\"errorTip\":\"\"}"
						+ "]"
				),
		SYNC_VISA (
				"SYNC_VISA", "同步签证数据",
				"["
						+ "{\"enName\":\"visaTime\",\"cnName\":\"有效期\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\"}"
						+ ",{\"enName\":\"planTime\",\"cnName\":\"预计出入境时间\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\",\"errorTip\":\"\"}"
						+ ",{\"enName\":\"tip\",\"cnName\":\"是否提示\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\",\"errorTip\":\"\"}"
						+ ",{\"enName\":\"records\",\"cnName\":\"出入境记录\",\"isNecessary\": false,\"isEncrypt\": false,\"checkRule\":\"\",\"errorTip\":\"\"}"
						+ "]"
				),
		// 同步客户端签证记录至客户端
		AUTHCODE (
				"AUTHCODE", "发送短信验证码",
				"["
						+ "{\"enName\":\"phoneNum\",\"cnName\":\"手机号\",\"isNecessary\": true,\"isEncrypt\": false,\"checkRule\":\"^[1][0-9]{10}$\",\"errorTip\":\"手机号为11位数字\"}"
						+ "]"
				),
		;
		
		private InterfaceType (String prefix, String alias, String defRules) {
			this.prefix = prefix;
			this.defRules = defRules;
		}
		
		// 校验配置文件属性名
		private String prefix;
		
		// 服务别名
		private String alias;
		
		// 配置文件中不存在时默认的校验规则
		private String defRules;
		
		public String getPrefix() {
			return prefix;
		}
		public void setPrefix(String prefix) {
			this.prefix = prefix;
		}
		public String getDefRules() {
			return defRules;
		}
		public void setDefRules(String defRules) {
			this.defRules = defRules;
		}

		public String getAlias() {
			return alias;
		}

		public void setAlias(String alias) {
			this.alias = alias;
		}
	}
	
	/**
	 * 参数校验
	 * @param params 参数
	 * @param type 服务类型
	 * @return 校验通过返回 success
	 */
	public static BusiResult<Object> verify(BusiResult<Object> ret, Map<String, String> params, InterfaceType type) {
		ret.setOk(false);
		ret.setCode(BusiCode.ERROR_9005.getCode());
		String rules = PropertyUtil.getValue("business", type.getPrefix());
		if (rules == null || "".equals(rules.trim())) {
			rules = type.getDefRules();
		}
		List<Map<String, Object>> ruleList = JsonUtil.jsonToList(rules);
		if (ruleList == null || ruleList.isEmpty()) {
			return ret.setMsg("请求参数验证出错");
		}
		// 参数个数验证 （此方法有局限性）
		/*if (params.size() > ruleList.size()) {
			return ret.setMsg("参数数量非法");
		}*/
		for (Map<String, Object> rule : ruleList) {
			String enName = (String)rule.get("enName");
			@SuppressWarnings("unused")
			String cnName = (String)rule.get("cnName");
			boolean isNecessary = (boolean)rule.get("isNecessary");
			@SuppressWarnings("unused")
			boolean isEncrypt = rule.get("isEncrypt") == null ? false : (boolean)rule.get("isEncrypt") ;
			String checkRule = (String)rule.get("checkRule");
			String errorTip = (String)rule.get("errorTip");
			String value = params.get(enName);
			// 如果不是必须参数且参数不存在 则继续校验下一个参数
			if (!isNecessary && !params.containsKey(enName)) {
				continue;
			}
			// 如果是必须参数且参数不存在 则返回
			if (isNecessary && !params.containsKey(enName)) {
				return ret.setMsg("参数[" + enName + "]不存在");
			}
			
			if ("".equals(checkRule)) {
				continue;
			}else if ("notEmpty".equals(checkRule)) {
				if (value == null || "".equals(value.trim())) {
					return ret.setMsg("参数[" + enName + "]为空");
				}
			} else if (!value.matches(checkRule)) {
				return ret.setMsg("参数[" + enName + "]" + errorTip);
			}
		}
		ret.setOk(true);
		return ret;
	}
}